Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

XFuWavLoad.cpp

Go to the documentation of this file.
00001 /*! \file 
00002  * X-Forge Util <br>
00003  * Copyright 2000-2003 Fathammer Ltd
00004  * 
00005  * \brief RIFF Wave loader
00006  * 
00007  * $Id: XFuWavLoad.cpp,v 1.5 2003/03/20 13:21:09 jetro Exp $
00008  * $Date: 2003/03/20 13:21:09 $
00009  * $Revision: 1.5 $
00010  */
00011 
00012 #include <xfcore/XFcCore.h>
00013 #include <xfutil/XFuWavLoad.h>
00014 
00015 
00016 class TempData
00017 {
00018 public:
00019     XFcFile *mF;
00020     INT16 mWavFormat;
00021     INT16 mChannels;
00022     INT32 mSampleRate;
00023     INT16 mBytesPerSample;
00024     INT32 mTotalBytes;
00025     void *mData;
00026 };
00027 
00028 
00029 // All the formats we're even remotely likely to support here:
00030 //#define WAVE_FORMAT_PCM         0x0001
00031 //#define WAVE_FORMAT_ADPCM       0x0002  /*  Microsoft Corporation  */
00032 //#define WAVE_FORMAT_IEEE_FLOAT  0x0003  /*  Microsoft Corporation  */
00033 //                                        /*  IEEE754: range (+1, -1]  */
00034 //                                        /*  32-bit/64-bit format as defined by */
00035 //                                        /*  MSVC++ float/double type */
00036 //#define  WAVE_FORMAT_ALAW       0x0006  /*  Microsoft Corporation  */
00037 //#define  WAVE_FORMAT_MULAW      0x0007  /*  Microsoft Corporation  */
00038 //#define  WAVE_FORMAT_MPEGLAYER3 0x0055  /*  ISO/MPEG Layer3 Format Tag */
00039 
00040 // currently this loader only supports 8bit mono PCM data.
00041 
00042 
00043 static INT loadHeader(TempData &d)
00044 {
00045     INT32 t; 
00046     INT32 chunkSize;
00047     
00048     d.mF->read(&t, 4, 1);
00049     if (t != 0x46464952) return 0; // "RIFF" reversed
00050     d.mF->read(&t, 4, 1); // skip file len
00051     d.mF->read(&t, 4, 1);
00052     if (t != 0x45564157) return 0; // "WAVE" reversed
00053     d.mF->read(&t, 4, 1);
00054     if (t != 0x20746d66) return 0; // "fmt " reversed
00055     d.mF->read(&chunkSize, 4, 1);
00056     d.mF->read(&d.mWavFormat, 2, 1);
00057     if (!(d.mWavFormat == 0x0001)) return 0; // unsupported format
00058     d.mF->read(&d.mChannels, 2, 1);
00059     if (!(d.mChannels == 1)) return 0; // unsupported number of mChannels
00060     d.mF->read(&d.mSampleRate, 4, 1);
00061     d.mF->read(&t, 4, 1); // skip "avgbytespersec"
00062     d.mF->read(&d.mBytesPerSample, 2, 1);
00063     if (!(d.mBytesPerSample == 1)) return 0; // unsupported bit/chn combination
00064     chunkSize -= 2 + 2 + 4 + 4 + 2;
00065     
00066     // skip the rest of the header, if any: 
00067     // (microsoft PCM has 2 more bytes, bits per sample,
00068     // which we can figure out already)
00069     d.mF->seek(d.mF->tell() + chunkSize, SEEK_SET);
00070     
00071     return 1;
00072 }
00073 
00074 
00075 XFcAudioBuffer * xfuLoadWav(const CHAR *filename, INT32 flags)
00076 {
00077     TempData d;
00078     
00079     d.mData = NULL;
00080     d.mF = XFcFile::open(filename, XFCSTR("rb"));
00081     if (d.mF == NULL) return NULL;
00082     if (!loadHeader(d)) 
00083     {
00084         d.mF->close();
00085         return NULL;
00086     }
00087     INT32 chunkId;
00088     
00089     // while not end of file
00090     while (d.mF->read(&chunkId, 4, 1)) 
00091     {
00092         INT32 chunkSize;
00093         d.mF->read(&chunkSize, 4, 1);
00094         if (chunkId == 0x61746164 && d.mData == NULL)
00095         {
00096             d.mData = (void *)new INT8[chunkSize];
00097             if (d.mData == NULL)
00098             {
00099                 d.mF->close();
00100                 return NULL;
00101             }
00102             d.mF->read(d.mData, chunkSize, 1);
00103             d.mTotalBytes = chunkSize;
00104         }
00105         else
00106         {
00107             // skip chunk:
00108             d.mF->seek(d.mF->tell() + chunkSize, SEEK_SET);
00109         }
00110     }
00111     d.mF->close();
00112     
00113     XFcAudioBuffer *sndBuf;
00114     // FIX ME: not d.mTotalBytes but TOTAL SAMPLES
00115     sndBuf = XFcAudioBuffer::create((FLOAT32)d.mSampleRate, flags & ~LW_SCALEHALF, d.mTotalBytes, 1.0, 0.5);
00116 
00117     if (sndBuf == NULL)
00118     {
00119         delete[] (INT8 *)d.mData;
00120         return NULL;
00121     }
00122 
00123     INT8 *buf = (INT8 *)XFcAudio::lock(sndBuf);
00124     if (flags & LW_SCALEHALF)
00125     {
00126         INT32 i;
00127         for (i = 0; i < d.mTotalBytes; ++i)
00128         {
00129             buf[i] = (INT8)(((((INT8 *)d.mData)[i] ^ 128) / 8) ^ 128);
00130         }
00131     }
00132     else
00133     {
00134         memcpy(buf, d.mData, d.mTotalBytes);
00135     }
00136 
00137     XFcAudio::unlock(sndBuf);
00138 
00139     delete[] (INT8 *)d.mData;
00140 
00141     return sndBuf;
00142 }
00143 
00144 
00145 XFcAudioBuffer * xfuLoadWav(const CHAR *filename)
00146 {
00147     return xfuLoadWav(filename, 0);
00148 }

   
X-Forge Documentation
Confidential
Copyright © 2002-2003 Fathammer
   
Documentation generated
with doxygen
by Dimitri van Heesch